#include "cansetmodel.h"
#include <QDebug>
#include "config.h"
#include "mainwindow.h"

//static const UINT kAbitTiming[] = {
//    0x00018B2E,//1Mbps
//    0x00018E3A,//800kbps
//    0x0001975E,//500kbps
//    0x0001AFBE,//250kbps
//    0x0041AFBE,//125kbps
//    0x0041BBEE,//100kbps
//    0x00C1BBEE //50kbps
//};
//static const UINT kDbitTiming[] = {
//    0x00010207,//5Mbps
//    0x0001020A,//4Mbps
//    0x0041020A,//2Mbps
//    0x0081830E //1Mbps
//};
//static const BYTE kTiming0[] = {
//    0x00,//1000kbps
//    0x00,//800kbps
//    0x00,//500kbps
//    0x01,//250kbps
//    0x03,//125kbps
//    0x04,//100kbps
//    0x09,//50kbps
//    0x18,//20kbps
//    0x31,//10kbps
//    0xBF //5kbps
//};
//static const BYTE kTiming1[] = {
//    0x14,//1000kbps
//    0x16,//800kbps
//    0x1C,//500kbps
//    0x1C,//250kbps
//    0x1C,//125kbps
//    0x1C,//100kbps
//    0x1C,//50kbps
//    0x1C,//20kbps
//    0x1C,//10kbps
//    0xFF //5kbps
//};
//static const unsigned kBaudrate[] = {
//    1000000,
//    800000,
//    500000,
//    250000,
//    125000,
//    100000,
//    50000,
//    20000,
//    10000,
//    5000
//};

CanSetModel::CanSetModel(QObject *parent) : QObject(parent)
{

}

//设置设备类型，设备通道索引，波特率
void CanSetModel::SetPara(int type, int index, char* br)
{   
    this->DeviceType = type;        //设备类型
    this->DeveiceIndex = index;     //设备通道索引
    memset(BaudRate, 0, sizeof(BaudRate));
    memcpy(this->BaudRate, br, strlen(br));            //波特率（char指针类型）
//    memset(BaudRateFd, 0, sizeof(BaudRateFd));
//    memcpy(this->BaudRateFd, br, strlen(br));            //波特率（char指针类型）
}

//can连接函数
bool CanSetModel::CanConnect()
{
    bool isCanFd = false;

    if(DeviceType == ZCAN_USBCAN1 || DeviceType == ZCAN_USBCAN2)
    {
        isCanFd = false;
    }
    //ZCAN_USBCAN1为设备类型  
    dhandle = ZCAN_OpenDevice(DeviceType, DeveiceIndex, 0);     //打开设备，赋给句柄值(0x40000_dhandle设备类型不同值不同）
    if (INVALID_DEVICE_HANDLE == dhandle)               //操作失败
    {
        qDebug( "打开设备失败" );
        return false;
    }
    IProperty* property = GetIProperty(dhandle);        //获取句柄属性(0x60847c6_cproperty变化的）
    if (NULL == property)               //获取失败
    {
        qDebug()<< "属性指针为空" ;
        ReleaseIProperty(property);     //释放属性配置
        ZCAN_CloseDevice(dhandle);      //关闭设备
        return false;
    }

    ZCAN_CHANNEL_INIT_CONFIG cfg;       //初始化CAN配置参数
    if(isCanFd)
    {
        //仲裁域波特率（IProperty属性的SetValue函数设置设备属性）
        if (property->SetValue("0/canfd_abit_baud_rate",BaudRateFd) != STATUS_OK)
        {
            qDebug() << "设置波特率FD失败" ;
            ReleaseIProperty(property);         //释放对应属性
            ZCAN_CloseDevice(dhandle);
            return false;
        }

        // 数据域波特率
        if (property->SetValue("0/canfd_dbit_baud_rate",BaudRate) != STATUS_OK)
        {

            qDebug() << "设置波特率失败" ;
            ReleaseIProperty(property);
            ZCAN_CloseDevice(dhandle);
            return false;
        }

        memset(&cfg, 0, sizeof(cfg));       //将按cfg字节对内存初始化，清0
        cfg.can_type = TYPE_CANFD;      //CANFD设备为TYPE_CANFD
        cfg.can.filter = 0;     //滤波方式，=1 表示单滤波， ，=0 表示双滤波 。
        cfg.can.mode = 0;       //正常模式, 1为只听模式
        cfg.can.acc_code = 0;   //验收码，同CAN 设备。
        cfg.can.acc_mask = 0xffffffff;      //屏蔽码，同CAN 设备。
    }
    else
    {
        //标准波特率
        if (property->SetValue("1/baud_rate", BaudRate) != STATUS_OK)
        {
            qDebug() << property->SetValue("0/baud_rate", BaudRate) << ":设置波特率，标识1为成功，0为失败";
            qDebug() << "设置标准波特率失败" ;
            ReleaseIProperty(property);
            ZCAN_CloseDevice(dhandle);

            qDebug() << BaudRate << "BaudRate值";
            return false;
        }
        memset(&cfg, 0, sizeof(cfg));
        cfg.can_type = TYPE_CAN;        //CAN设备为TYPE_CAN
        cfg.can.filter = 0;     //滤波方式，=1 表示单滤波， ，=0 表示双滤波 。
        cfg.can.mode = 0;       //正常模式, 1为只听模式
        cfg.can.acc_code = 0;   //验收码，同CAN 设备。
        cfg.can.acc_mask = 0xffffffff;      //屏蔽码，同CAN 设备。
    }

    chHandle = ZCAN_InitCAN(dhandle, 0, &cfg);      //初始化CAN
    if (INVALID_CHANNEL_HANDLE == chHandle)
    {
        qDebug() << "初始化通道失败";
        ReleaseIProperty(property);
        ZCAN_CloseDevice(dhandle);
        return false;
    }
    if (ZCAN_StartCAN(chHandle) != STATUS_OK)       //启动CAN通道
    {
        qDebug() << "启动通道失败" ;
        ReleaseIProperty(property);
        ZCAN_CloseDevice(dhandle);
        return false;
    }

    isStart =true;

    return true;

}

//添加can数据
void CanSetModel::AddData(const ZCAN_Receive_Data *data, UINT len)
{
    QString item;
    for (UINT i = 0; i < len; ++i)
    {
        const ZCAN_Receive_Data& can = data[i];
        const canid_t& id = can.frame.can_id;

        CanDataBase *cdb = new CanDataBase();
        cdb->SetTime(data->timestamp);
        cdb->SetData(GET_ID(id),(unsigned char*)can.frame.data,can.frame.can_dlc,IS_EFF(id),IS_RTR(id));        //设置数据（包括ID，实际帧数据，帧负载数据长度，扩展帧，远程帧）

        AddData(cdb);
    }
}

//添加canFD数据
void CanSetModel::AddData(const ZCAN_ReceiveFD_Data *data, UINT len)
{
    QString item;
    for (UINT i = 0; i < len; ++i)
    {
        const ZCAN_ReceiveFD_Data& canfd = data[i];
        const canid_t& id = canfd.frame.can_id;

        CanDataBase *cdb = new CanDataBase();
        cdb->SetTime(data->timestamp);

        cdb->SetData(GET_ID(id),(unsigned char*)canfd.frame.data,canfd.frame.len,IS_EFF(id),IS_RTR(id));        //设置数据（包括ID，实际帧数据，帧负载数据长度，扩展帧，远程帧）

        AddData(cdb);
    }
}

//添加时间数据及can数据
void CanSetModel::AddData(CanDataBase *cdb)
{
    cdb->SetTime(QDateTime::currentDateTime());     //获取当前时间
    cdb->GetStringData();       //获取Latin1编码字符
   // qDebug()<<"ID:" <<cdb->Id<<"数据："<<cdb->StrData;

    emit this->DataUpdata(cdb);     //发射更新信号
}

//数据接收
void CanSetModel::DataReceive()
{
    ZCAN_Receive_Data can_data[100];    //接收can数据结构体数组（can报文信息）1.frame报文数据信息 2.时间戳，单位毫秒基于设备启动时间
    ZCAN_ReceiveFD_Data canfd_data[100];
    UINT len;
    while(isStart)
    {
        if (len = ZCAN_GetReceiveNum(chHandle, TYPE_CAN))       // ZCAN_GetReceiveNum 获取缓冲区中CAN报文数目（参数2：0=CAN 1=CANFD 2=合并接收）数量
        {
            len = ZCAN_Receive(chHandle, can_data, 100, 50);    //接收CAN报文
            AddData(can_data, len);
        }
        if (len = ZCAN_GetReceiveNum(chHandle, TYPE_CANFD))
        {
            len = ZCAN_ReceiveFD(chHandle, canfd_data, 100, 50);
            AddData(canfd_data, len);
        }
    }
}

//关闭can设备
void CanSetModel::CanClose()
{
    // ReleaseIProperty(property);
    ZCAN_CloseDevice(dhandle);      //关闭设备

    isStart = false;
}

//bool CanSetModel::CanSend(CanDataBase *data)
//{

//    ZCAN_Transmit_Data frame;
//    memset(&frame, 0, sizeof(frame));


//    frame.frame.can_id = data->Id ;
//    frame.frame.can_dlc =data->Len;
//    for( int i = 0; i < data->Len; i++ )
//    {
//        frame.frame.data[i] =  data->Data[i];
//    }

//    if (ZCAN_Transmit(chHandle, &frame, 1) != 1)
//    {
//        qDebug() << "发送数据失败" ;
//        return false;
//    }

//   // data->sTime = frame.

//    return true;
//}



